import { debounce } from '@/utils/debounce';
import { getToken } from '@/utils/token';
import { history } from '@umijs/max';
import { notification } from 'antd';
import axios, {
  AxiosInstance,
  AxiosRequestConfig,
  AxiosResponse,
  InternalAxiosRequestConfig,
} from 'axios';
import qs from 'qs';

class MyRequest {
  instance: AxiosInstance | undefined;

  constructor() {
    this.init();
  }

  init() {
    this.instance = axios.create({
      baseURL: `${process.env.UMI_APP_BASE_URL}`,
    });

    // 请求拦截
    this.instance.interceptors.request.use(
      (config: InternalAxiosRequestConfig) => {
        if (!config.url?.includes('public') && getToken()) {
          config.headers.Authorization = getToken();
        }
        return config;
      },
      (error) => {
        return Promise.reject(error);
      },
    );

    this.instance.interceptors.response.use(
      (response: AxiosResponse) => {
        if (
          response.data.code === 401 &&
          !response.config.url?.endsWith('getAccount')
        ) {
          this.redirect();
        }
        return response;
      },
      (error) => {
        if (error && error.request.status) {
          switch (error.request.status) {
            case 401:
            case 404:
          }
        }
        return Promise.reject(error);
      },
    );
  }

  check() {
    if (!this.instance) this.init();
  }

  redirect = debounce(() => {
    history.push('/');
    notification.error({ message: '登录失效，请重新登录' });
  });
}

const myRequest = new MyRequest();

export const request = async <T>(
  url: string,
  config?: AxiosRequestConfig,
): Promise<T> => {
  myRequest.check();
  const { data } = await myRequest.instance!.request<T>({
    url,
    ...config,
    paramsSerializer: {
      serialize: function (params: any) {
        return qs.stringify(params);
      },
    },
  });
  return data;
};

export function axiosFactory(baseURL: string) {
  return axios.create({
    baseURL,
  });
}

export default myRequest.instance;
